﻿namespace Atomic.Mvc.Validators
{
    using System;
    using System.Collections.Generic;
    using Atomic.Common;
    using Atomic.Caching;

    /// <summary>
    /// 实体验证。
    /// </summary>
    public class EntityValidator
    {
        /// <summary>
        /// 实体验证对象的字典。
        /// </summary>
        private readonly static IDictionary<Type, IEntityValidator> _validator = new Dictionary<Type, IEntityValidator>();

        /// <summary>
        /// 实体验证的实例。
        /// </summary>
        private readonly static EntityValidator _entityValidator = new EntityValidator();

        /// <summary>
        /// 当前实体验证对象。
        /// </summary>
        public static EntityValidator Current
        {
            get
            {
                return _entityValidator;
            }
        }

        #region 验证实体。 ValidatorState Validate(object item)

        /// <summary>
        /// 验证实体。
        /// </summary>
        /// <param name="item">实体对象。</param>
        /// <returns>实体验证状态。</returns>
        public ValidatorState Validate(object item)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }

            IEntityValidator validator = this.Create(item.GetType());

            if (validator != null)
            {
                return validator.Validate(item);
            }

            return null;
        }

        /// <summary>
        /// 创建 IEntityValidator 实例。
        /// </summary>
        /// <param name="modelType">对象类型。</param>
        /// <returns>IEntityValidator 实例。</returns>
        private IEntityValidator Create(Type modelType)
        {
            IEntityValidator validator = null;

            if (_validator.ContainsKey(modelType))
            {
                validator = _validator[modelType];
            }
            else
            {
                Type clientType = typeof(DataAnnotationsEntityValidator<>).MakeGenericType(modelType);
                validator = Activator.CreateInstance(clientType, this, modelType) as IEntityValidator;

                if (validator != null)
                {
                    _validator[modelType] = validator;
                }
            }

            return validator;
        }

        #endregion

        #region 验证实体。 ValidatorState Validate<TSource>(TSource item) where TSource : class

        /// <summary>
        /// 验证实体。
        /// </summary>
        /// <typeparam name="TSource">实体类型。</typeparam>
        /// <param name="item">实体对象。</param>
        /// <returns>实体验证状态。</returns>
        public ValidatorState Validate<TSource>(TSource item) where TSource : class
        {
            var validator = this.GetValidator<TSource>();

            if (validator != null)
            {
                return validator.Validate(item);
            }

            return null;
        }

        /// <summary>
        /// 获得 IValidator - TSource 实例。
        /// </summary>
        /// <typeparam name="TSource">实体类型。</typeparam>
        /// <returns>IValidator - TSource 实例。</returns>
        private IValidator<TSource> GetValidator<TSource>() where TSource : class
        {
            var key = typeof(TSource).ToString();

            var validator = CacheManager.Current.Get<IValidator<TSource>>(key);

            if (validator == null)
            {
                if (AtomicContainer.Container.IsRegisterd<IValidator<TSource>>())
                {
                    validator = AtomicContainer.Container.Resolve<IValidator<TSource>>();

                    CacheManager.Current.Set(key, validator);
                }
            }

            return validator;
        }

        #endregion
    }
}